/**
 * @p.md
 * 
 * Future 类，用于异步获取 Actor 响应
 */
import { PID } from './pid';
import { Process } from './process';
import { ActorSystem } from './actorSystem';
import { Events } from './eventStream';

export class DeadLetterResponse {}

/**
 * 表示一个异步操作的结果
 */
export class Future {
  private pid: PID;
  private _timeoutId?: NodeJS.Timeout;
  private _callbacks: ((error: Error | null, result?: any) => void)[] = [];
  private _completed: boolean = false;
  private _result: any;
  private _error: Error | null = null;
  private _retryCount: number = 0;
  private readonly maxRetries: number = 3;
  private readonly retryDelay: number = 1000; // 1秒

  constructor(private system: ActorSystem, private timeout: number = 10000) { // 默认超时时间改为10秒
    // 创建唯一的Future ID
    const futureId = `future$${Date.now()}-${Math.floor(Math.random() * 1000000)}`;
    this.pid = new PID('local', futureId);
    
    // 注册Future进程
    const process = {
      sendUserMessage: (pid: PID, message: any) => {
        console.log(`[FUTURE] Received message for ${pid.toString()}`);
        this.complete(null, message);
      },
      sendSystemMessage: () => {},
      stop: () => {
        this.cleanup();
      }
    };
    
    system.processRegistry.add(process, futureId);
    
    // 监听DeadLetter事件
    system.eventStream.subscribe((msg: any) => {
      if (msg.pid === this.pid.toString()) {
        console.log(`[FUTURE] Received DeadLetter for ${this.pid.toString()}`);
        this.handleDeadLetter();
      }
    });
    
    // 设置超时
    if (timeout > 0) {
      console.log(`[FUTURE] Setting timeout for ${timeout}ms`);
      this._timeoutId = setTimeout(() => {
        console.log(`[FUTURE] TIMEOUT triggered after ${timeout}ms for future: ${this.pid.address}/${this.pid.id}`);
        this.handleTimeout();
      }, timeout);
    }
  }

  private handleTimeout() {
    if (this._completed) return;
    
    if (this._retryCount < this.maxRetries) {
      console.log(`[FUTURE] Attempt ${this._retryCount + 1}/${this.maxRetries} timed out, retrying...`);
      this._retryCount++;
      
      // 清除旧的超时计时器
      if (this._timeoutId) {
        clearTimeout(this._timeoutId);
      }
      
      // 设置新的超时
      this._timeoutId = setTimeout(() => {
        this.handleTimeout();
      }, this.timeout);
      
      // 触发重试事件
      this.system.eventStream.publish({
        type: 'FutureRetry',
        futureId: this.pid.id,
        attempt: this._retryCount
      });
      
      return;
    }
    
    // 所有重试都失败后，设置超时错误
    this.setError(new Error(`Future timed out after ${this.timeout * (this.maxRetries + 1)}ms (${this.maxRetries + 1} attempts)`));
  }

  private handleDeadLetter() {
    if (this._completed) return;
    
    if (this._retryCount < this.maxRetries) {
      console.log(`[FUTURE] DeadLetter received, attempt ${this._retryCount + 1}/${this.maxRetries}, retrying...`);
      this._retryCount++;
      
      // 延迟重试
      setTimeout(() => {
        // 触发重试事件
        this.system.eventStream.publish({
          type: 'FutureRetry',
          futureId: this.pid.id,
          attempt: this._retryCount
        });
      }, this.retryDelay);
      
      return;
    }
    
    // 所有重试都失败后，设置错误
    this.setError(new Error(`Message delivery failed after ${this.maxRetries + 1} attempts`));
  }

  getPID(): PID {
    return this.pid;
  }

  onComplete(callback: (error: Error | null, result?: any) => void): void {
    if (this._completed) {
      callback(this._error, this._result);
    } else {
      this._callbacks.push(callback);
    }
  }

  toPromise(): Promise<any> {
    return new Promise((resolve, reject) => {
      this.onComplete((error, result) => {
        if (error) {
          reject(error);
        } else {
          resolve(result);
        }
      });
    });
  }

  private complete(error: Error | null, result?: any): void {
    if (this._completed) return;
    
    console.log(`[FUTURE] Completing future ${this.pid.toString()}`);
    this._completed = true;
    this._error = error;
    this._result = result;
    
    this.cleanup();
    
    console.log(`[FUTURE] Notifying ${this._callbacks.length} callbacks`);
    this._callbacks.forEach(callback => callback(error, result));
    this._callbacks = [];
  }

  private setError(error: Error): void {
    console.log(`[FUTURE] Setting error: ${error.message}`);
    this.complete(error);
  }

  private cleanup(): void {
    console.log(`[FUTURE] Cleaning up future ${this.pid.toString()}`);
    
    // 清除超时计时器
    if (this._timeoutId) {
      console.log(`[FUTURE] Clearing timeout`);
      clearTimeout(this._timeoutId);
      this._timeoutId = undefined;
    }
    
    // 从进程注册表中移除
    this.system.processRegistry.remove(this.pid);
    
    // 取消订阅DeadLetter事件
    console.log(`[FUTURE] Future completed, unsubscribing from DeadLetter events`);
  }
} 